package com.smf.lsc.database.filter;

import java.sql.SQLException;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;

import com.alibaba.druid.filter.FilterAdapter;
import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.proxy.jdbc.JdbcParameter;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.util.JdbcUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 大结果集控制
 * @author ln
 *
 */
@Slf4j
public class ResultSetLimitFilter extends FilterAdapter {

	@Value("${spring.datasource.resultsetlimit.errorline:300000}")
	long errorLine;
	
	@Override
	public boolean resultSet_next(FilterChain chain, ResultSetProxy resultSet) throws SQLException {
		boolean hasNext = super.resultSet_next(chain, resultSet);
		if (hasNext) {
			int row = resultSet.getFetchRowCount();
			if (errorLine > 0 && row >= errorLine) {
				resultSetLimitError(resultSet);
			}
		}
		return hasNext;
	}

	/**
	 * 结果集超出警戒线处理
	 * @param resultSet
	 * @throws SQLException
	 */
	private void resultSetLimitError(ResultSetProxy resultSet) throws SQLException {
		StringBuffer errStrBuff = new StringBuffer();
		errStrBuff.append("\n =========[DB-ERROR] 查询结果集超出系统限制 "+ errorLine);
		errStrBuff.append("\n =========> Preparing: ").append(resultSet.getSql());
		Map<Integer, JdbcParameter> map = resultSet.getStatementProxy().getParameters();
		String parameters="";
		for (Map.Entry<Integer, JdbcParameter> entry : map.entrySet()) {
			parameters+=entry.getKey()+"("+ JdbcUtils.getTypeName(entry.getValue().getSqlType()) +"),";
		}
		if (parameters.length() > 0) {
			parameters = parameters.substring(0, parameters.length() - 1);
        }
		errStrBuff.append("\n =========> parameters: ").append(parameters);
		log.error(errStrBuff.toString());
		throw new SQLException("[DB-ERROR] 查询结果集超出系统限制 "+ errorLine +",请检查ErrorLine配置");
	}
}
